/*
This file is part of "hp-like 4x4 keypad library".

"hp-like 4x4 keypad library" is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

"hp-like 4x4 keypad library" is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with "hp-like 4x4 keypad library".  If not, see <http://www.gnu.org/licenses/>.

Copyleft: kenzanin[at]gmail[dot]com ||suka[dot]isnaini[at]politeknikaceh[dot]ac[dot]id
forum: solderen.tk/forum
*/

#include <avr/io.h>
#include <util/delay.h>
#include "keypad.h"

void keypad_init(void)
{
    KEYPAD_PORT  = (1<<PIN0)|(1<<PIN1)|(1<<PIN2)|(1<<PIN3)|(1<<PIN4)|(1<<PIN5)|(1<<PIN6)|(1<<PIN7);
    KEYPAD_DDR  |= ((1<<PIN0)|(1<<PIN1)|(1<<PIN2)|(1<<PIN3));
    KEYPAD_DDR  &=~((1<<PIN4)|(1<<PIN5)|(1<<PIN6)|(1<<PIN7));
}

const unsigned char __keypad__[]=
{
    1,2,3,15,4,5,6,14,7,8,9,13,10,0,11,12
};

uint8_t keypad_read(void)
{
    union
    {
        struct
        {
            uint8_t lo:4;
            uint8_t hi:4;
        };
        uint8_t all;
    } status;

    uint8_t	var01	= 0;

    status.hi=1;
    for(var01=0; var01<4 && status.hi ; var01++)
    {
        KEYPAD_PORT=~(1<<var01);
        _delay_ms(10);
        switch(KEYPAD_PIN&0xf0)
        {
        case 0b11100000:
            status.all=0;
            break;
        case 0b11010000:
            status.all=1;
            break;
        case 0b10110000:
            status.all=2;
            break;
        case 0b01110000:
            status.all=3;
            break;
        default:
            break;
        }
    }
    if(status.hi)
    {
        return 0x10;
    }
    else
    {
        status.lo+=(var01-1)*4;
        status.lo=__keypad__[status.lo];
        return status.all;
    }
}

const unsigned char __flash __keypad_hp__[][4]=
{
    {'0','0','0','0'},{'1','A','B','C'},{'2','D','E','F'},\
    {'3','G','H','I'},{'4','J','K','L'},{'5','M','N','O'},\
    {'6','P','Q','R'},{'7','S','T','U'},{'8','W','X','Y'},\
    {'9','Z','0','0'},{0x0d,0x0d,0x0d,0x0d},{'#','@','%','&'},\
    {'D',';','"','.'},{0x08,0x08,0x08,0x08},{'B','(',')','<'},\
    {'A','>','/',','}
};

/*
 * return:
 * 1 status.lo == data keypad
 * 2 statys.hi == status keypad
 * 		0 sucses
 *		1 keypad tidak di tekan
 */
char    tom_past=0;
int8_t  hp_index=0;
int16_t hp_punya_hehe(int8_t _mode)
{
    union
    {
        struct
        {
            uint8_t lo:8;
            uint8_t hi:8;
        };
        uint16_t all;
    } status;

    int8_t var01=0;

    status.all=0;
    var01=keypad_read();
    if(var01 & 0x10)
    {
        status.hi=0x01;
        return status.all;
    }
    if(_mode && (tom_past==var01))
    {
        if(hp_index<MAX_INDEX-1)
        {
            hp_index++;
        }
        else
        {
            hp_index=0;
        }
        status.hi=0x02;
    }
    else
    {
        hp_index=0;
        tom_past=var01;
    }
    status.lo=__keypad_hp__[var01][hp_index];
    return status.all;
}
